package com.example.soss.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.soss.entity.*;
import com.example.soss.mapper.CourseMapper;
import com.example.soss.mapper.OrderMapper;
import com.example.soss.util.UserContextHolder;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class CourseService {

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private OrderMapper orderMapper;

    @Autowired
    private OrderService orderService;




    //缓存课程列表30秒钟
//    private static Cache<String, Map<String, Object>> cacheCourseList = CacheBuilder.newBuilder()
//            .initialCapacity(100)
//            .expireAfterWrite(30, TimeUnit.SECONDS).build();

    //页面缓存
    private static Cache<String, String> pageCache = CacheBuilder.newBuilder()
            .initialCapacity(100)
            .expireAfterWrite(30, TimeUnit.SECONDS).build();


    //标记课程余额为0的课程
    private static Map<Integer, Object> map = new HashMap<>();


    @PostConstruct
    private void init() {
        for (int i = 1; i < 31; i++) {
            map.put(i, false);
        }
    }


    /**
     * 选课（DB）
     *
     * @param courseId
     * @param stuId
     * @return
     */
    public Result selectCourseByDB(int courseId, int stuId) {

        //map标记
        if ((Boolean) map.get(courseId)) {
            log.info("内存标记判空");
            return Result.failure(ResultEnum.EMPTY);
        }

        //查询该课程库存
        Course course = courseMapper.selectById(courseId);
        if (course.getAmount() < 1) {
            map.put(courseId, true);
            return Result.failure(ResultEnum.EMPTY);
        }
        //检查是否重复选课
        Integer data = orderMapper.selectOrder(stuId); //不回表查询
        if (data != null) {
            return Result.failure(ResultEnum.REPEAT);
        }

        //下单
        return orderService.order(courseId, stuId);
    }


    /**
     * 退课
     *
     * @param courseId
     * @param stuId
     */
    @Transactional
    public Result dropCourse(int courseId, int stuId) {


        //该课程剩余人数+1
        Course course = courseMapper.selectById(courseId);
        course.setAmount(course.getAmount() + 1);
        courseMapper.updateById(course);

        //删除该选课记录
        QueryWrapper<Order> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.eq("stu_id", stuId);
        orderQueryWrapper.eq("course_id", courseId);
        orderMapper.delete(orderQueryWrapper);

        map.put(courseId, false);
        map.put(-1 * stuId, null);
        return Result.success(ResultEnum.DROP_SUCCESS);

    }

    /**
     * 获取页面缓存(1-全部课程，0-可选课程)
     *
     * @param key
     * @return
     */
    public String getPageCache(String key) {
        //从缓存中取数据

        String html = pageCache.getIfPresent(key);
        return html;

    }

    /**
     * 设置页面缓存(1-全部课程，0-可选课程)
     *
     * @param key
     * @param html
     * @return
     */
    public void setPageCache(String key, String html) {
        pageCache.put(key, html);

    }


    /**
     * 从缓存中分页查询全部课程(1-全部课程，0-可选课程)
     *
     * @param currentPage
     * @param limit
     * @return
     */
/*    public Map<String, Object> getCourseListFromCacheByPage(int currentPage, int limit, int flag) {
        //从缓存中取数据
        String key = flag + ":" + currentPage;
        Map<String, Object> data = cacheCourseList.getIfPresent(key);
        //如果缓存为空，从数据库中获取放入缓存
        if (data == null) {
            data = Maps.newHashMap();
            data.put("totalSize", getAllCourseCount(flag));
            data.put("courseList", getAllCourseList(currentPage, limit, flag));
            cacheCourseList.put(key, data);
            log.info("从DB中获取选课列表----------------------");
            return data;
        } else {
            log.info("从缓存中获取选课列表------------------------");
            return data;
        }
    }*/




    /**
     * 分页查询课程（1为全部课程，0为空可选课程）
     * @return
     */
    public List<Course> getAllCourseList(int currentPage, int limit, int flag) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        if (flag == 0) {
            queryWrapper.gt("amount", 0);
        }
        Page<Course> coursePage = courseMapper.selectPage(new Page<Course>(currentPage, limit), queryWrapper);
        return coursePage.getRecords();
    }

    /**
     * 查询课程数量（1为全部课程，0为剩余可选课程）
     *
     * @returnk
     */
    public int getAllCourseCount(int flag) {
        if (flag == 1) return courseMapper.selectCount(null);
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("amount", 0);
        return courseMapper.selectCount(queryWrapper);

    }

    /**
     * 新增课程
     *
     * @param course
     * @return
     */
    public Result addCourse(Course course) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", course.getName());
        queryWrapper.eq("teacher", course.getTeacher());
        Course storeData = courseMapper.selectOne(queryWrapper);
        if (storeData != null) return Result.failure(ResultEnum.ADD_FAILURE);
        courseMapper.insert(course);
        return Result.success(ResultEnum.SUCCESS);
    }

    /**
     * 删除课程
     *
     * @param courseId
     * @return
     */
    public Result deleteCourse(int courseId) {
        Course course = courseMapper.selectById(courseId);
        if (course.getStatus() == 1) return Result.failure(ResultEnum.DELETE_FAILURE);
        course.setStatus(1);
        courseMapper.updateById(course);
        return Result.success(ResultEnum.DELETE_SUCCESS);
    }


    /**
     * 更新课程信息
     *
     * @param course
     * @return
     */
    public Result updateCourse(Course course) {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", course.getName());
        queryWrapper.eq("teacher", course.getTeacher());
        Course storeData = courseMapper.selectOne(queryWrapper);
        if (storeData != null) {
            return Result.failure(ResultEnum.UPDATE_FAILURE);
        }
        courseMapper.updateById(course);
        return Result.success(ResultEnum.UPDATE_SUCCESS);
    }


    /**
     * 查看已选课程
     * @param stuId
     * @return
     */
    public Course getSelectedCourse(int stuId) {
        Course course = (Course)map.get(-1 * stuId);

        if (course == null) {
            Order order = orderMapper.selectOne(new QueryWrapper<Order>().eq("stu_id", stuId));
            if (order == null) {
                return null;
            }
            course = courseMapper.selectById(order.getCourseId());
            map.put(-1 * stuId, course);
            log.info("从DB中获取已选课程");
            return course;
        }
        log.info("从缓存中获取已选课程");
        return course;
    }


    public Result getResult(int courseId) {
        Student user = UserContextHolder.getUser();
        if (user == null) {
            return Result.failure(ResultEnum.NOT_LOGIN);
        }
        Integer integer = orderMapper.selectOrder(user.getId());
        if (integer == null) {
            Course course = courseMapper.selectById(courseId);
            if (course.getAmount() < 1) {
                return Result.failure(ResultEnum.EMPTY);
            } else {
                return Result.failure(ResultEnum.QUEUING);
            }
        }
        return Result.success(ResultEnum.SUCCESS);
    }
}
